/**
 * 编辑基类
 */

import MouseEvent from "../../event/types/MouseEvent"

export default class Edit {

  constructor() {
    this._viewer = undefined
    this._overlay = undefined
    this._anchors = []
    this._delegate = undefined
    this._pickedAnchor = undefined
    this._isMoving = false
    this._clampToGround = true
    this._layer = undefined
    this._anchorLayer = undefined
    this._plotEvent = undefined
    this._tooltip = undefined
    this._mouseEvent = undefined
    this._message = undefined
    this._options = {}
    this._positions = []
  }

  _mountEntity() { }

  _mountAnchor() { }

  _onClick(e) { }

  _onMouseMove(e) {
    e = this.getMouseInfo(e.endPosition)
    this._tooltips.showAt(e.windowPosition, this._message)
    if (!this._isMoving) {
      return false
    }
    if (this._pickedAnchor && this._pickedAnchor.position) {
      let properties = this._pickedAnchor.properties.getValue(
        Cesium.JulianDate.now()
      )
      let position = this._clampToGround ? e.surfacePosition : e.position
      if (!position) {
        return false
      }
      this._pickedAnchor.position.setValue(position)
      this._positions[properties.index] = position
    }
  }

  _onRightClick(e) { }

  bindEvent() {
    this._mouseEvent.on(Cesium.ScreenSpaceEventType.LEFT_CLICK, this._onClick, this)
    this._mouseEvent.on(Cesium.ScreenSpaceEventType.MOUSE_MOVE, this._onMouseMove, this)
    this._mouseEvent.on(Cesium.ScreenSpaceEventType.RIGHT_CLICK, this._onRightClick, this)
  }

  unbindEvent() {
    this._tooltips.enable = false
    this._mouseEvent.off(Cesium.ScreenSpaceEventType.LEFT_CLICK, this._onClick, this)
    this._mouseEvent.off(Cesium.ScreenSpaceEventType.MOUSE_MOVE, this._onMouseMove, this)
    this._mouseEvent.off(Cesium.ScreenSpaceEventType.RIGHT_CLICK, this._onRightClick, this)
    this._mouseEvent.destroy()
  }

  /**
   *
   * @param position
   * @param index
   * @param isMid
   * @param isCenter
   */
  createAnchor(position, index, isMid = false, isCenter = false) {
    let image = isMid
      ? this._options.icon_midAnchor
      : isCenter
        ? this._options.icon_center
        : this._options.icon_anchor
    let anchor = this._anchorLayer.add({
      position: position,
      billboard: {
        image: image,
        width: 12,
        height: 12,
        eyeOffset: new Cesium.Cartesian3(0, 0, -500)
      },
      properties: {
        isMid: isMid,
        index: index,
        message : isMid ? '拖动此点增加新点' : '拖动此点编辑位置'
      }
    })
    this._anchors.push(anchor)
  }

  /**
   * 计算中点
   * @param p1
   * @param p2
   * @returns {Cartesian3}
   */
  computeMidPosition(p1, p2) {
    let c1 = Cesium.Ellipsoid.WGS84.cartesianToCartographic(p1)
    let c2 = Cesium.Ellipsoid.WGS84.cartesianToCartographic(p2)
    let cm = new Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5)
    return Cesium.Ellipsoid.WGS84.cartographicToCartesian(cm)
  }

  /**
   * 开始编辑
   * @param plot
   * @param clampToGround
   */
  start(plot, clampToGround) {
    this._viewer = plot.viewer
    this._tooltips = plot.tooltips
    this._tooltips.enable = true
    this._layer = plot.overlayLayer
    this._anchorLayer = plot.anchorLayer
    this._plotEvent = plot.plotEvent
    this._options = plot.options
    this._clampToGround = clampToGround
    this._mouseEvent = new MouseEvent(this._viewer)
    this._mountEntity()
    this._mountAnchor()
    this.bindEvent()
  }

  /**
   * 获取鼠标位置信息
   * @param {} position 
   * @returns 
   */

  getMouseInfo(position) {
    let scene = this._viewer.scene
    let target = scene.pick(position)
    let cartesian = undefined
    let surfaceCartesian = undefined
    let wgs84Position = undefined
    let wgs84SurfacePosition = undefined
    if (scene.pickPositionSupported) {
      cartesian = scene.pickPosition(position)
    }
    if (cartesian) {
      let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian)
      if (c) {
        wgs84Position = {
          lng: Cesium.Math.toDegrees(c.longitude),
          lat: Cesium.Math.toDegrees(c.latitude),
          alt: c.height
        }
      }
    }
    if (
      scene.mode === Cesium.SceneMode.SCENE3D &&
      !(this._viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider)
    ) {
      let ray = scene.camera.getPickRay(position)
      surfaceCartesian = scene.globe.pick(ray, scene)
    } else {
      surfaceCartesian = scene.camera.pickEllipsoid(
        position,
        Cesium.Ellipsoid.WGS84
      )
    }
    if (surfaceCartesian) {
      let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(surfaceCartesian)
      if (c) {
        wgs84SurfacePosition = {
          lng: Cesium.Math.toDegrees(c.longitude),
          lat: Cesium.Math.toDegrees(c.latitude),
          alt: c.height
        }
      }
    }

    return {
      target: target,
      windowPosition: position,
      position: cartesian,
      wgs84Position: wgs84Position,
      surfacePosition: surfaceCartesian,
      wgs84SurfacePosition: wgs84SurfacePosition
    }
  }
}